package com.zlf.config;

import com.zlf.controller.ShiroConstant;
import com.zlf.realm.CustomerRealm;
import com.zlf.redis.RedisCacheManager;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName ShiroConfiguration
 * @Description Shiro的核心配置类
 * @Author zlf
 * @Date 2021/5/24 10:10
 */
@Configuration
public class ShiroConfiguration {

    /*
    创建shiroFilter  //负责拦截所有请求
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager); // 给filter设置安全管理器

        /*
         配置系统受限资源、配置系统公共资源
         */
        Map<String, String> map = new HashMap<String, String>();
        map.put("/user/login", "anon"); // anon 设置为公共资源，放行要注意anon和authc的顺序
        map.put("/user/register", "anon");
        map.put("/register.jsp", "anon");
        map.put("/user/getImage", "anon");
        map.put("/index.jsp", "authc"); // authc 请求这个资源需要认证和授权

        shiroFilterFactoryBean.setLoginUrl("/login.jsp"); // 默认认证界面路径
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }

    /*
    创建安全管理器
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm); // 给安全管理器设置
        return securityManager;
    }

    /*
    创建自定义realm
     */
    @Bean
    public Realm getRealm() {
        CustomerRealm customerRealm = new CustomerRealm();
        // 设置密码匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        // 设置加密方式
        credentialsMatcher.setHashAlgorithmName(ShiroConstant.HASH_ALGORITHM_NAME.MD5);
        // 设置散列次数
        credentialsMatcher.setHashIterations(ShiroConstant.HASH_ITERATORS);
        customerRealm.setCredentialsMatcher(credentialsMatcher);

        // 设置缓存管理器
        // customerRealm.setCacheManager(new EhCacheManager()); // 使用EhCache缓存,只需要引入shiro-ehcache包即可
        customerRealm.setCacheManager(new RedisCacheManager()); // 使用redis缓存，引入包后重写CacheManager接口
        // 开启全局缓存
        customerRealm.setCachingEnabled(true);
        // 开启认证缓存并指定缓存名称
        customerRealm.setAuthenticationCachingEnabled(true);
        customerRealm.setAuthenticationCacheName("authenticationCache");
        // 开启授权缓存并指定缓存名称
        customerRealm.setAuthorizationCachingEnabled(true);
        customerRealm.setAuthorizationCacheName("authorizationCache");
        return customerRealm;
    }

}
